www.gusucode.com > VC++ 信息加密聊天源代码-源码程序 > VC++ 信息加密聊天源代码-源码程序\code\SecChat\SecretKeyEdit.cpp
//Download by http://www.NewXing.com // SecretKeyEdit.cpp : implementation file // #include "stdafx.h" #include "secretchat.h" #include "SecretKeyEdit.h" #include "RSA.h" #include "SecretChatDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CSecretKeyEdit dialog CSecretKeyEdit::CSecretKeyEdit(CWnd* pParent /*=NULL*/) : CDialog(CSecretKeyEdit::IDD, pParent) { //{{AFX_DATA_INIT(CSecretKeyEdit) m_email = _T(""); m_qq = _T(""); m_userName = _T(""); m_secretKeyEdit = _T(""); //}}AFX_DATA_INIT } void CSecretKeyEdit::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CSecretKeyEdit) DDX_Text(pDX, IDC_EMAIL, m_email); DDV_MaxChars(pDX, m_email, 32); DDX_Text(pDX, IDC_QQ, m_qq); DDV_MaxChars(pDX, m_qq, 32); DDX_Text(pDX, IDC_USERNAME, m_userName); DDV_MaxChars(pDX, m_userName, 32); DDX_Text(pDX, IDC_SECRETKEY, m_secretKeyEdit); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CSecretKeyEdit, CDialog) //{{AFX_MSG_MAP(CSecretKeyEdit) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CSecretKeyEdit message handlers DWORD WINAPI create_secret_key_thread(LPVOID param) //创建密钥线程函数 { CSecretKeyEdit * pKey = (CSecretKeyEdit *)param; //查看文件是否存在 CFileFind find; if( find.FindFile(pKey->m_user_private_key_file_name) ) { //提示文件存在并退出 MessageBox( NULL, "文件已经存在", "生成私钥文件", MB_ICONEXCLAMATION); pKey->SetWindowText("创建新的用户密钥"); pKey->m_bCreate = TRUE; //能再创建 return 0; } //生成密钥和用户信息 private_key key; key.create(); key.vlong_to_SK(pKey->m_secretKey.sk); key.vlong_to_PK(pKey->m_secretKey.pk); pKey->CStringToChar( pKey->m_secretKey.userName, pKey->m_userName, 32); pKey->CStringToChar( pKey->m_secretKey.qq, pKey->m_qq, 32); pKey->CStringToChar( pKey->m_secretKey.email, pKey->m_email, 32); pKey->m_secretKey.version = SECRETKEY_VERSION; pKey->m_secretKey.privateOrPublic = SECRETKEY_PRIVATE; pKey->m_secretKey.ID = SECRETKEY_ID; //把密钥信息写入文件,私钥文件 CFile file; file.Open( pKey->m_user_private_key_file_name, CFile::modeCreate | CFile::modeReadWrite | CFile::typeBinary); file.Write( &pKey->m_secretKey, sizeof(SecretKey)); //写入信息 file.Close(); //把密钥信息写入文件,公钥文件 pKey->CreatePublicKey(pKey->m_user_private_key_file_name); //提示成功 MessageBox( NULL, "已经生成密钥,可以安全的进行通讯。", "密聊", MB_ICONINFORMATION); //更新列表,如果没m_publicKeyManagerDlg窗口就会出错 //pSecretChatDlg->m_setupDlg.ShowTabWindow(1); pKey->m_bCreate = TRUE; //可以再创建 pKey->SetWindowText("创建新的用户密钥"); return 0; } void CSecretKeyEdit::OnOK() { if(!m_bCreate) { MessageBox( "创建密钥中", "密聊", MB_ICONINFORMATION); return; } CSecretChatDlg * pSecretChatDlg = (CSecretChatDlg *)AfxGetMainWnd(); if(!UpdateData()) return; CEdit *pTemp; if(m_userName == "") { pTemp = (CEdit *)GetDlgItem(IDC_USERNAME); pTemp->SetFocus(); //不能为空 MessageBox( "不能为空", "warning", MB_ICONEXCLAMATION); return; } else if(m_qq == "") { pTemp = (CEdit *)GetDlgItem(IDC_QQ); pTemp->SetFocus(); //不能为空 MessageBox( "不能为空", "warning", MB_ICONEXCLAMATION); return; } else if(m_email == "") { pTemp = (CEdit *)GetDlgItem(IDC_EMAIL); pTemp->SetFocus(); //不能为空 MessageBox( "不能为空", "warning", MB_ICONEXCLAMATION); return; } if(m_select == SELECT_CREATE) { SetWindowText("创建新的用户密钥 (正在创建中)"); m_user_private_key_file_name = pSecretChatDlg->m_appName + "\\user\\" + m_userName + ".sk"; m_bCreate = FALSE; //不能再创建 unsigned long nThreadID; ::CreateThread( NULL, 0, create_secret_key_thread, this, 0, &nThreadID); return; } else //SELECT_PRIVATE和SELECT_PUBLIC的处理相同 { CStringToChar( m_secretKey.qq, m_qq, 32); CStringToChar( m_secretKey.email, m_email, 32); //更改密钥信息写入私钥文件 CFile file; file.Open( m_fileName,//密钥的文件全路径 CFile::modeReadWrite | CFile::typeBinary); file.SeekToBegin(); file.Write( &m_secretKey, sizeof(SecretKey)); //写入信息 file.Close(); } CDialog::OnOK(); } void CSecretKeyEdit::OnCancel() { if(!m_bCreate) { MessageBox( "创建密钥中", "密聊", MB_ICONINFORMATION); return; } CDialog::OnCancel(); } BOOL CSecretKeyEdit::OnInitDialog() { CDialog::OnInitDialog(); CEdit *pUserName = (CEdit *)GetDlgItem(IDC_USERNAME); CStatic *pSecretKeyStatic = (CStatic *)GetDlgItem(IDC_SECRETKEYSTATIC); CButton *pOK = (CButton *)GetDlgItem(IDOK); CEdit *psecretKey = (CEdit *)GetDlgItem(IDC_SECRETKEY); if(m_select == SELECT_CREATE) { pSecretKeyStatic->SetWindowText("生成密钥说明:"); pUserName->SetReadOnly(FALSE); SetWindowText("创建新的用户密钥"); pOK->SetWindowText("生成"); CString str; str.LoadString(IDS_CREATEPUBLICKEYHELP); psecretKey->SetWindowText(str); //psecretKey->SetWindowText(" \"密聊\"采用 2048bit 的 RSA 数据加密算法对数据进行加密和数字签名,在使用前必须生成用户的私钥和公钥。\r\n 只要通过安全通道相互把公钥传递给通讯方后,彼此就可以进行安全的通话和身份验证了。\r\n 生成私有密钥文件 [用户名.sk] 和公开密钥文件 [用户名.pk] 的过程需要稍等几分钟..."); } else if(m_select == SELECT_PRIVATE) { pSecretKeyStatic->SetWindowText("私钥信息(2048bit):"); pUserName->SetReadOnly(); SetWindowText("用户私钥编辑"); pOK->SetWindowText("更改"); } else if(m_select == SELECT_PUBLIC) { pSecretKeyStatic->SetWindowText("公钥信息(2048bit):"); pUserName->SetReadOnly(); SetWindowText("好友公钥编辑"); pOK->SetWindowText("更改"); } m_bCreate = TRUE; //可以再创建 return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } CString CSecretKeyEdit::CharToHexToString(char m) //把一个字符转换成十六进制再用字符表示 { char hex; CString strHex; //左边4位的表示 hex = m & (char)0xf0; hex = hex >> 4; hex = hex & (char)0xf; //有时被移进来的为会为1 switch(hex) { case 0: strHex = "0"; break; case 1: strHex = "1"; break; case 2: strHex = "2"; break; case 3: strHex = "3"; break; case 4: strHex = "4"; break; case 5: strHex = "5"; break; case 6: strHex = "6"; break; case 7: strHex = "7"; break; case 8: strHex = "8"; break; case 9: strHex = "9"; break; case 10: strHex = "A"; break; case 11: strHex = "B"; break; case 12: strHex = "C"; break; case 13: strHex = "D"; break; case 14: strHex = "E"; break; case 15: strHex = "F"; break; } //右边4位的表示 hex = m & (char)0xf; switch(hex) { case 0: strHex += "0"; break; case 1: strHex += "1"; break; case 2: strHex += "2"; break; case 3: strHex += "3"; break; case 4: strHex += "4"; break; case 5: strHex += "5"; break; case 6: strHex += "6"; break; case 7: strHex += "7"; break; case 8: strHex += "8"; break; case 9: strHex += "9"; break; case 10: strHex += "A"; break; case 11: strHex += "B"; break; case 12: strHex += "C"; break; case 13: strHex += "D"; break; case 14: strHex += "E"; break; case 15: strHex += "F"; break; } return strHex; } int CSecretKeyEdit::validateSecretKey(CString fileName) { //验证是不是密钥文件(私钥为1,公钥为2,都不是为0) m_fileName = fileName; CFile file; if(!file.Open( fileName, CFile::modeReadWrite | CFile::typeBinary)) return 0; if(file.GetLength() != sizeof(SecretKey)) return 0; file.SeekToBegin(); file.Read(&m_secretKey, sizeof(SecretKey)); file.Close(); if(m_secretKey.ID != SECRETKEY_ID) return 0; m_userName = CharToCString(m_secretKey.userName, 32); m_qq = CharToCString(m_secretKey.qq, 32); m_email = CharToCString(m_secretKey.email, 32); char chTemp[2048 / 8]; if(m_secretKey.privateOrPublic == SECRETKEY_PRIVATE) { ::MoveMemory( chTemp, //目标 (char *)&m_secretKey.sk, //源内容 2048 / 8); } else { ::MoveMemory( chTemp, //目标 (char *)&m_secretKey.pk, //源内容 2048 / 8); } //将密钥换成二进制显示 m_secretKeyEdit = ""; for(int i = 0;i < 256;i++) { m_secretKeyEdit += CharToHexToString(chTemp[i]) + " "; if(!(i == 0 || i == 255)) { if((i + 1) % 16 == 0) m_secretKeyEdit += "\r\n"; } } return m_secretKey.privateOrPublic; } void CSecretKeyEdit::CStringToChar(char *ch, CString str,int n) { //字符串转到字符数组 for( int i = 0;i < str.GetLength();i++) { if( i == n) return; ch[i] = str[i]; } if( i == n) return; //为了使数组char[n]不越界,才要这样做的 ch[i] = NULL; } CString CSecretKeyEdit::CharToCString(char *ch, int n/*char数组的大小*/) { ////字符数组转到字符串 CString str; char * pbuf = new char[n + 1]; pbuf[n] = NULL; for( int i = 0;i < n;i++) pbuf[i] = ch[i]; str = pbuf; delete[] pbuf; return str; } BOOL CSecretKeyEdit::CreatePublicKey(CString fileName) //生成公钥 { SecretKey secretKey; CFile file; if(!file.Open( fileName, CFile::modeReadWrite | CFile::typeBinary)) return FALSE; if(file.GetLength() != sizeof(SecretKey)) return FALSE; file.SeekToBegin(); file.Read(&secretKey, sizeof(SecretKey)); file.Close(); //私钥文件名要转换成对应的公钥文件名 fileName.SetAt( fileName.GetLength() - 2, 'p'); //把密钥信息写入文件,公钥文件 char chTemp[2048 / 8]; for(int i = 0;i < (2048 / 8);i++) { chTemp[i] = 0; } ::MoveMemory( (char *)&secretKey.sk, //目标 chTemp, //源内容 2048 / 8); secretKey.privateOrPublic = SECRETKEY_PUBLIC; //查看文件是否存在 WIN32_FIND_DATA wfd; HANDLE hSearch = ::FindFirstFile( fileName,//密钥的文件全路径 &wfd); if( hSearch != INVALID_HANDLE_VALUE) //文件存在 { //提示文件存在并退出 if(MessageBox( "文件已经存在。覆盖 " + fileName + " 文件吗?", "生成公钥文件", MB_YESNO | MB_ICONQUESTION) == IDNO) { return FALSE; } } file.Open( fileName,//密钥的文件全路径 CFile::modeCreate | CFile::modeReadWrite | CFile::typeBinary); file.Write( &secretKey, sizeof(SecretKey)); //写入信息 file.Close(); return TRUE; }